<?php

namespace app\system\controller;

use app\common\tool\Upload;
use app\system\model\Attachment as AttachmentModel;
use app\system\model\AttachmentGroup;
use OSS\OssClient;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use think\facade\View;

class Attachment extends Base
{
    public function paths($path)
    {
        if (empty($path)) {
            $path = root_path('public') . 'upload';
        } else {
            $path = root_path('public') . 'upload' . $path;
        }
        return $path;
    }
    /**
     * 列表
     */
    public function lst()
    {
        if (request()->isPost()) {
            $attachment = new AttachmentModel;
            $limit = input('limit');
            $data = $attachment->getAll($limit);
            return tocode(0, "成功", $data->items(), $data->total());
        }
        return view();
    }
    /**
     * 本地迁移到云端
     */
    public function local_migrate()
    {
        //适用于大多数运行模式(不包括命令行模式)
        set_time_limit(0); //设置不限执行时间
        ini_set('max_execution_time', 0);
        ignore_user_abort(true); //忽略客户端中断
        //nginx等可能需要达到4k才会输出buffer,所有先输出一些空字符串
        $str = str_repeat(' ', 65536);
        $str .= '立即输出，正在后台继续迁移：' . date('Y-m-d H:i:s');
        header('X-Accel-Buffering: no'); // 关闭加速缓冲, 在nginx模式需要开启此行
        header("Content-Type: text/html;charset=utf-8");
        header("Connection: close"); //告诉浏览器不需要保持长连接
        header('Content-Length: ' . strlen($str)); //告诉浏览器本次响应的数据大小只有上面的echo那么多
        ob_end_flush();
        ob_start();
        echo $str;
        ob_flush();
        flush();
        //至此,连接已经关闭. 但是进程还不会结束, 以下程序还能运行但不会输出
        sleep(3);
        $this->migrate();
        // $this->oss_migrates_to_the_local();
    }
    /**
     * 列表
     */
    public function images()
    {
        if (request()->isPost()) {
            $attachment = new AttachmentModel;
            $map = input('post.');
            $map['key'] = $map['key'];
            $data = $attachment->getAlls($map);
            $other['type'] = $map['key'];
            return tocode(0, "成功", $data);
        }
        return view();
    }
    public function group()
    {
        $type = input('type');
        $res = AttachmentGroup::where('type', $type)->select();
        return tocode(200, 'ok', $res);
    }
    public function group_info()
    {
        if (request()->isPost()) {
            $id = input('id');
            $title = input('title');
            $data = ['name' => $title];
            $att = new AttachmentGroup;
            if (!empty($id)) {
                $att = AttachmentGroup::find($id);
            }
            $att->save($data);
            return tocode(200, "成功");
        }
    }
    public function del_group()
    {
        if (request()->isPost()) {
            $id = input('id');
            if (empty($id)) {
                return tocode(100, "ID不能为空");
            }
            AttachmentGroup::destroy($id);
            return tocode(200, "成功");
        }
    }
    public function move_group()
    {
        if (request()->isPost()) {
            $group_id = input('group_id');
            $data = input('data');
            if (empty($group_id)) {
                return tocode(100, "group_id不能为空");
            }
            AttachmentModel::where('file_id', 'in', $data)->update(['group_id' => $group_id]);
            return tocode(200, "成功");
        }
    }
    public function file($paths)
    {
        //遍历文件夹
        $dir = opendir($paths);
        //循环读取
        $res = [];
        $i = 0;
        while ($n = readdir($dir)) {
            $url = $paths . '/' . $n;
            if ($n != "." && $n != "..") {
                $res[$i]['name'] = $n;
                $res[$i]['size'] = format_bytes(getFolderSize($url)); //格式化字节
                $res[$i]['time'] = date('Y-m-d H:i:s', filemtime($url));
                $res[$i]['type'] = 0;
                // $res[$i]['path'] = $path;
                if (!is_dir($url)) { //判断路径是不是目录
                    $res[$i]['type'] = isFileType($url); //判断文件的类型
                }
            }
            $i++;
        }
        closedir($dir); //关闭目录资源
        $res = arrayToSort($res, 'type', "SORT_ASC"); //二维数组按某个字段排序
        return $res;
    }
    /**
     * 添加提交
     */
    public function add()
    {
        $attachment = new AttachmentModel;
        if (request()->isPost()) {
            $data = input('post.');
            if (empty($data)) {
                return tocode(100, '数据不能为空');
            }
            $info = $attachment->info($data);
            if (!$info) {
                return tocode(100, '添加失败');
            }
            return tocode(200, '添加成功！');
        }
        return view('info');
    }
    /**
     * 修改提交
     */
    public function edit()
    {
        $attachment = new AttachmentModel;
        if (request()->isAjax()) {
            $id = input('id');
            if (empty($id)) {
                return tocode(100, 'ID不能为空');
            }
            if (request()->isPost()) {
                $data = input('post.');
                if (empty($data)) {
                    return tocode(100, '数据不能为空');
                }
                $info = $attachment->info($data);
                if (!$info) {
                    return tocode(100, '编辑失败');
                }
                return tocode(200, '编辑成功！');
            }
            $res = $attachment->getOne($id);

            return tocode(200, 'ok', $res);
        }
        return view('info');
    }
    /**
     * 状态
     */
    public function status()
    {
        if (request()->isPost()) {
            $id = input('id');
            $status = input('status');
            if (empty($id)) {
                return tocode(100, 'ID不能为空');
            }
            if (empty($status)) {
                $status = 0;
            }
            $attachment = new AttachmentModel;
            $status = $attachment->status($id, $status);
            if (!$status) {
                return tocode(100, '修改状态失败');
            }
            return tocode(200, '修改状态成功！');
        }
    }
    /**
     * 删除单条
     */
    public function del()
    {
        $attachment = new AttachmentModel;
        if (request()->isAjax()) {
            $id = input('id');
            if (empty($id)) {
                return tocode(100, 'ID不能为空');
            }
            $del = $attachment->handleAll($id, 2);
            if (!$del) {
                return tocode(100, '删除失败');
            }
            return tocode(200, '删除成功！');
        }
    }
    public function delAll()
    {
        $data = input('data');
        try {
            AttachmentModel::where('file_id', 'in', $data)->delete();
        } catch (\Exception $e) {
            return tofalse($e->getMessage());
        }
        return totrue('删除成功！');
    }
    /**
     * 批量启用、禁用、删除
     */
    public function handleAll()
    {
        $ids = input('id');
        $type = input('type', 0);
        if (empty($ids)) {
            return tocode(100, 'ID不能为空');
        }
        if (empty($type)) {
            $type = 0;
        }
        $attachment = new AttachmentModel();
        $all = $attachment->handleAll($ids, $type);
        switch ($type) {
            case '1':
                $name = '启用';
                break;
            case '2':
                $name = '删除';
                break;
            default:
                $name = '禁用';
                break;
        }
        if (!$all) {
            return tocode(100, $name . '失败');
        }
        return tocode(200, $name . '成功！');
    }
    /**
     * 数据库一键OSS迁移到本地
     */
    public function oss_migrates_to_the_local()
    {
        $res = AttachmentModel::where('storage', 0)->select()->toArray();
        foreach ($res as $k => $v) {
            $url = config_group('config_images_setup_url') . $v['url'];
            $name = explode('/', $v['url']);
            $path = root_path('public') . "upload/" . $name[0] . '/';
            if (!is_file($path . $name[1])) {
                add_dir_file($path, $name[1], file_get_contents($url));
            }
        }
        echo 'ok';
    }
    /**
     * 数据库一键迁移到七牛云
     * 从服务器搬到七牛云
     */
    public function migrate()
    {
        $res = AttachmentModel::where('storage', 0)->select();
        $storage = config_group('config_images_setup');
        foreach ($res as $k => $v) {
            $path = root_path() . "/public/upload/" . $v->url;
            if (is_file($path)) {
                switch ($storage) {
                    case '1':
                        $data = self::qiUpload($path);
                        $url = $data['key'];
                        $sha1 = $data['hash'];
                        break;
                    case '2':
                        $aliyun = config('filesystem.disks.aliyun');
                        $data = self::aliUpload($path);
                        $url = str_replace($aliyun['url'], '', $data['oss-request-url']);
                        $sha1 = $data['x-oss-hash-crc64ecma'];
                        break;
                    case '3': //迁移到图床
                        $aliyun = config('filesystem.disks.aliyun');
                        $data = self::sm_ms($path);
                        $url = str_replace('\/', '/', $data['path']);
                        $sha1 = empty($data['hash']) ? $v->hash : $data['hash'];
                        break;
                }
                $update = [
                    'id' => $v->id,
                    'storage' => $storage,
                    'url' => $url,
                    'sha1' => $sha1,
                ];
                $v::update($update);
                // unlink($path);
            }
            // sleep(1);
        }
        return 'ok';
    }
    /**
     * Class QiUpload 图片上传至七牛云
     */
    public static function qiUpload($path)
    {
        $file = pathinfo($path);
        $qiniu = config('filesystem.disks.qiniu');
        //获取上传文件
        $imageData = file_get_contents($path);
        $finfo = finfo_open(FILEINFO_MIME);
        $mimetype = explode(';', finfo_file($finfo, $path))[0];
        finfo_close($finfo);
        //构建鉴权对象
        $auth = new Auth($qiniu['accessKey'], $qiniu['secretKey']);
        $token = $auth->uploadToken($qiniu['bucket']);
        $key = explode('/', $mimetype)[0] . '/' . $file['basename'];
        $up = new UploadManager();
        $mime = $mimetype;
        list($rest, $err) = $up->put($token, $key, $imageData, null, $mime);
        return $rest;
    }
    public static function aliUpload($path)
    {
        $file = pathinfo($path);
        $aliyun = config('filesystem.disks.aliyun');
        //获取上传文件
        $imageData = file_get_contents($path);
        $finfo = finfo_open(FILEINFO_MIME);
        $mimetype = explode(';', finfo_file($finfo, $path))[0];
        finfo_close($finfo);
        $key = explode('/', $mimetype)[0] . '/' . $file['basename'];
        $ossClient = new OssClient($aliyun['accessId'], $aliyun['accessSecret'], $aliyun['endpoint']);
        $res = $ossClient->uploadFile($aliyun['bucket'], $key, $path);
        return $res;
    }
    public static function sm_ms($path)
    {
        $upda_res = Upload::sm_ms($path);
        if (!empty($upda_res)) {
            if ($upda_res['success'] == true) {
                $savename = $upda_res['data'];
                return $savename;
            } else {
                if ($upda_res['code'] == 'image_repeated') {
                    $savename['path'] = str_replace('https://i.loli.net', '', $upda_res['images']);
                    return $savename;
                }
            }
        }
    }
}
